<?php

namespace App\Admin;

use App\Admin\Layout\Content;
use App\Models\Menu;
use Illuminate\Database\Eloquent\Model;

class Admin
{
    /**
     * 组件要添加的额外的js代码
     *
     * @var array
     */
    public static $script = [];

    /**
     * 组件要引入的额外的css文件
     *
     * @var array
     */
    public static $css = [];

    /**
     * 组件要引入的额外的js文件
     *
     * @var array
     */
    public static $js = [];

    /**
     * 返回数据表格
     *
     * @param          $model
     * @param \Closure $callable
     * @return Grid
     */
    public function grid($model, \Closure $callable)
    {
        return new Grid($this->getModel($model), $callable);
    }

    /**
     * 返回内容
     *
     * @param \Closure $callable
     * @return Content
     */
    public function content(\Closure $callable)
    {
        return new Content($callable);
    }

    /**
     * 返回表单
     *
     * @param          $model
     * @param \Closure $callable
     * @return Form
     */
    public function form($model, \Closure $callable)
    {
        return new Form($this->getModel($model), $callable);
    }

    /**
     * 返回树状组件
     *
     * @param $model
     * @return Tree
     */
    public function tree($model)
    {
        return new Tree($this->getModel($model));
    }

    /**
     * 后台左侧菜单数据
     *
     * @return array
     */
    public function menu()
    {
        return (new Menu())->toTree();
    }

    /**
     * 返回参数代表的模型实例
     *
     * @param $model
     * @return mixed
     */
    public function getModel($model)
    {
        if ($model instanceof Model) {
            return $model;
        }
        if (is_string($model) && class_exists($model)) {
            return $this->getModel(new $model());
        }

        throw new \InvalidArgumentException("{$model} 不是一个有效的模型");
    }

    /**
     * 返回后台控制器的namespace
     *
     * @return string
     */
    public function controllerNamespace()
    {
        return ltrim(
                implode('\\', array_map('ucfirst', explode(DIRECTORY_SEPARATOR, str_replace(app()->basePath(), '', 'Admin')))),
                '\\'
            ) . '\\Controller';
    }

    /**
     * 向表单中添加额外的css或js文件
     *
     * @param $asset
     * @param $type
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|void
     */
    protected static function asset($asset, $type)
    {
        if (!is_null($asset)) {
            self::$$type = array_merge(self::$css, (array)$$type);

            return;
        }

        $asset = array_get(Form::collectFieldAssets(), $type, []);

        static::$$type = array_merge(static::$$type, $asset);

        return view("admin.partials.$type", [$type => array_unique(static::$$type)]);
    }

    /**
     * 向form表单添加一个css文件路径,或者获取引入css的html代码
     *
     * @param null $css
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|void
     */
    public static function css($css = null)
    {
        return static::asset($css, 'css');
    }

    /**
     * 向form表单添加一个js文件路径,或者获取引入js的html代码
     *
     * @param null $js
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|void
     */
    public static function js($js = null)
    {
        return static::asset($js, 'js');
    }

    /**
     * 组件向表单添加js代码,或者生成js代码的html代码
     *
     * @param string $script
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|void
     */
    public static function script($script = '')
    {
        if (!empty($script)) {
            self::$script = array_merge(self::$script, (array)$script);

            return;
        }

        return view(
            'admin.partials.script',
            ['script' => array_unique(self::$script)]
        );
    }

    /**
     * 获取后台当前认证的用户
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function user()
    {
        return \Auth::guard('web')->user();
    }

    /**
     * 根据uri路径,自动补上后台前缀
     *
     * @param $uri
     * @return string
     */
    public static function path($uri)
    {
        return '/admin/' . trim($uri, '/');
    }

    /**
     * 返回后台全路径地址
     *
     * @param $uri
     * @return string
     */
    public static function url($uri)
    {
        return url(static::path($uri));
    }

    /**
     * 获取一个菜单下所有子菜单的uri,用来判断是否激活该菜单
     *
     * @param $items
     * @return array
     */
    public static function childrenUris($items)
    {
        $uris = [];
        foreach ($items as $i) {
            if (isset($i['children'])) {
                $uris = array_merge(self::childrenUris($i['children']), $uris);
            } else {
                $uris[] = trim(static::path($i['uri']), '/');
            }
        }

        return $uris;
    }
}